<template>
  <div class="map-wrapper">
    <div id="container" :style="{ height: `${mapHeight}px` }"></div>
    <a-card class="order-box" size="small">
      <VueDraggable ref="listRef" @end="addPolyline" v-model="storeOrderList" :animation="150" ghostClass="ghost" :style="{ height: `${mapHeight - 100}px`, overflowY: 'auto' }">
        <div class="store-order-item" v-for="(item, index) in storeOrderList" :key="item.id">
          <div class="no">{{ index + 1 }}</div>
          <div class="content">
            <p class="line">
              <span style="margin-right: 0.5em">{{ item?.name }}</span>
              <span :style="{ color: item.type === 1 ? '#df5352' : '#8085a2' }">{{ item?.no }}</span>
              <span style="float: right; cursor: pointer"><BarsOutlined style="font-size: 22px" /></span>
            </p>
            <p class="line">{{ item.address }}</p>
            <p class="line">
              <span style="margin-right: 0.5em; color: #8085a2">{{ item?.create_time }}</span>
              <span style="margin-right: 0.5em; color: #8085a2">{{ item?.salesman_rename }}</span>
              <span style="margin-right: 0.5em; color: #8085a2">{{ item?.remark }}</span>
            </p>
            <div class="order-info-line">
              <span>{{ item.totalVolume.toFixed(2) }}m³</span>
              <span>|</span>
              <span>{{ item.totalWidth.toFixed(2) }} kg</span>
              <span>|</span>
              <span>￥{{ item.order_amount.toFixed(2) }}</span>
            </div>
          </div>
          <span style="position: absolute; right: -10%; top: 50%; transform: translateY(-50%); cursor: pointer" @click="delLoadOrder(item)">
            <MinusCircleFilled style="color: red; font-size: 22px" />
          </span>
        </div>
      </VueDraggable>
      <a-card class="total-box" size="small">
        <p class="total-box-line">
          <span>
            体积&nbsp;&nbsp;&nbsp;&nbsp;订:
            <strong>{{ checkedOrderVolumeTotal.sales }}</strong>
            m³
          </span>
          <span>
            退:
            <strong>{{ checkedOrderVolumeTotal.refund }}</strong>
            m³
          </span>
        </p>
        <p class="total-box-line">
          <span>
            重量&nbsp;&nbsp;&nbsp;&nbsp;订:
            <strong>{{ checkedOrderWeightTotal.sales }}</strong>
            kg
          </span>
          <span>
            退:
            <strong>{{ checkedOrderWeightTotal.refund }}</strong>
            kg
          </span>
        </p>
        <p class="total-box-line">
          <span>
            金额&nbsp;&nbsp;&nbsp;&nbsp;订:
            <strong>{{ _.floor(checkedOrderAmountTotal.sales, 2) }}</strong>
            元
          </span>
          <span>
            退: <strong>{{ _.floor(checkedOrderAmountTotal.refund, 2) }}</strong>
            元
          </span>
        </p>
        <p class="total-box-line">
          <span>
            数量&nbsp;&nbsp;&nbsp;&nbsp;订:
            <strong>{{ checkedOrderCountTotal.sales }}</strong>
            件
          </span>
          <span>
            退:
            <strong>{{ checkedOrderCountTotal.refund }}</strong>
            件
          </span>
        </p>
      </a-card>
      <template #actions>
        <div class="order-box-footer">
          <span style="margin-right: 20px"></span>
          <div>
            <a-button style="margin-right: 8px" @click="changeSubmitModal(true)">新增</a-button>
            <a-button type="primary" style="margin-right: 8px" @click="submitTask">保存</a-button>
          </div>
        </div>
      </template>
    </a-card>
    <a-modal v-model:open="showSubmit" title="选择订单" width="80%" @cancel="changeSubmitModal(false)">
      <!---------- 查询表单form begin ----------->
      <a-form class="smart-query-form smart-query-form-max">
        <a-form-item label="单据日期" class="smart-margin-bottom0">
          <a-range-picker v-model:value="queryForm.create_time" valueFormat="YYYY-MM-DD" allow-clear :presets="TIME_RANGE_PRESETS" @change="onSearch" />
        </a-form-item>
        <a-form-item label="订单号" class="smart-margin-bottom0">
          <a-input v-model:value.trim="queryForm.no" placeholder="配送单号" allow-clear />
        </a-form-item>

        <a-form-item label="订单类型" class="smart-margin-bottom0">
          <EnumSelect enum-name="ORDER_STATRS_ENUM" v-model:value="queryForm.order_type" placeholder="订单类型" @submit="onSearch" />
        </a-form-item>

        <a-form-item class="smart-query-form-item">
          <a-button-group>
            <a-button type="primary" html-type="submit" @click="onSearch">
              <template #icon>
                <SearchOutlined />
              </template>
              查询
            </a-button>
            <a-button @click="resetQuery">
              <template #icon>
                <ReloadOutlined />
              </template>
              重置
            </a-button>
          </a-button-group>
        </a-form-item>
      </a-form>
      <!---------- 查询表单form end ----------->
      <!---------- 表格操作行 begin ----------->
      <a-row class="smart-table-btn-block">
        <div class="smart-table-operate-block">
          <!-- <a-button @click="toMap" type="primary" v-privilege="'goods:add'"> 地图派单 </a-button> -->
        </div>
        <div class="smart-table-setting-block">
          <TableOperator v-model="columns" :tableId="TABLE_ID_CONST.BUSINESS.ERP.GOODS" :refresh="queryData" />
        </div>
      </a-row>
      <!---------- 表格操作行 end ----------->
      <a-table size="small" :dataSource="tableData" :loading="tableLoading" :columns="columns" rowKey="id" bordered :scroll="{ x: 'max-content', y: 400 }" :pagination="false" :showSorterTooltip="false" :row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange, preserveSelectedRowKeys: true }"> </a-table>

      <template #footer>
        <div style="display: flex; justify-content: space-between">
          <div>
            <a-pagination showSizeChanger showQuickJumper show-less-items :pageSizeOptions="PAGE_SIZE_OPTIONS" :defaultPageSize="queryForm.limit" v-model:current="queryForm.page" v-model:pageSize="queryForm.limit" :total="total" @change="queryData" @showSizeChange="queryData" :show-total="(total) => `共${total}条`" />
          </div>
          <div>
            <a-button style="margin-right: 8px" @click="changeSubmitModal(false)">取消</a-button>
            <a-button type="primary" style="margin-right: 8px" @click="addOrder">确定</a-button>
          </div>
        </div>
      </template>
    </a-modal>
  </div>
</template>
<script lang="ts" setup>
import _ from 'lodash'
import { message, Modal } from 'ant-design-vue'
import AMapLoader from '@amap/amap-jsapi-loader'
import EnumSelect from '@/components/framework/enum-select/index.vue'
import { useUserStore } from '@/store/modules/user-store'
import { salesApi } from '@/api/business/sale/sales-api'
import { taskApi } from '@/api/business/logistics/delivery-api'
import { QUERY_FORM_OP } from '@/constants/support/query-form-op-const'
import { PAGE_SIZE_OPTIONS, TIME_RANGE_PRESETS } from '@/constants/system/common-const'
import { TABLE_ID_CONST } from '@/constants/support/table-id-const'
import location_fullfilled from '@/assets/images/logo/location_fullfilled.png'
import location_pending from '@/assets/images/logo/location_pending.png'
import location_active from '@/assets/images/logo/location_active.png'
import map_ck from '@/assets/images/logo/map_ck1.png'
import { VueDraggable } from 'vue-draggable-plus'
import { useQuery } from '@/hooks/web/use-query-hook'
import { useEnums } from '@/hooks/plugins/useEnums'
import { GOODS_UNIT_TYPE } from '@/constants/business/goods-const'
let map: any = null
let AMap: any = null
const icons = {
  location_pending,
  location_active,
  location_fullfilled,
  map_ck
}
const userStore = useUserStore()
const router = useRouter()
const route = useRoute()
const { getDescByValue } = useEnums()

// 地图高度
const mapHeight = ref(0)

// 初始化地图
function initMap() {
  window._AMapSecurityConfig = {
    securityJsCode: '98ed597fdab99b3580ded9e3d1f19d4e'
  }
  const loadMapConfig = {
    key: 'e3ad28f39ebf5c7d5fb1d7153fb2f3b4', // 申请好的Web端开发者Key，首次调用 load 时必填
    version: '2.0', // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
    plugins: ['AMap.LabelsLayer', 'AMap.Polyline'] //需要使用的的插件列表，如比例尺'AMap.Scale'，支持添加多个如：['...','...']
  }
  const mapConfig: any = {
    zoom: 14,
    zooms: [5, 20],
    center: userStore.getCenterLocal.map(Number),
    resizeEnable: true
  }

  AMapLoader.load(loadMapConfig).then(async (res) => {
    AMap = res
    // 渲染地图
    mapHeight.value = document.querySelector('.map-wrapper')?.clientHeight || 0
    map = new AMap.Map('container', mapConfig)
    // 请求订单列表
    await getStoreOrderList()
    map.setFitView()
  })
}

// 添加网点坐标
const storesMarkers = ref([])
function addMarker() {
  // 创建LabelsLayer图层
  const labelsLayer = new AMap.LabelsLayer({
    zooms: [2, 20], // 设置可见级别范围
    zIndex: 1000, // 设置zIndex
    collision: false // 设置标签是否允许碰撞
  })
  // 添加仓库标记
  const warehouseMarker = new AMap.LabelMarker({
    position: new AMap.LngLat(userStore.getCenterLocal.map(Number)[0], userStore.getCenterLocal.map(Number)[1]), // 仓库的经纬度
    name: '',
    icon: {
      type: 'image',
      image: icons['map_ck'], // 使用仓库图标
      size: [28, 28],
      anchor: 'bottom-center'
    },
    text: {
      content: '',
      offset: [0, 20],
      style: {
        fontSize: 10,
        fontWeight: 'normal',
        fillColor: '#000'
      }
    }
  })

  storesMarkers.value = storeOrderList.value
    .filter((item) => item.lon && item.lat)
    .map((item, index) => {
      return new AMap.LabelMarker({
        position: new AMap.LngLat(item.lon, item.lat),
        name: item.name,
        extData: item,
        zooms: [2, 20],
        rank: 1,
        icon: {
          type: 'image',
          image: icons[item.type === 1 ? 'location_pending' : 'location_fullfilled'],
          size: [24, 24],
          anchor: 'bottom-center'
        },
        text: {
          content: `${index + 1}`,
          offset: [0, 20],
          style: {
            fontSize: 10,
            fontWeight: 'normal',
            fillColor: item.type === 1 ? '#fff' : '#000'
          }
        }
      })
    })
  // 添加监听事件
  storesMarkers.value.forEach((item) => {
    let infoWindow = null
    item.on('mouseover', (e) => {
      infoWindow = initWindow(e)
      infoWindow.open(map, item.getPosition())
    })
    item.on('mouseout', () => {
      infoWindow.close()
    })
  })

  // 添加仓库标记到图层
  labelsLayer.add(warehouseMarker)
  labelsLayer.add(storesMarkers.value)
  map.add(labelsLayer)
}

// 绘制路径
let polyline = undefined
function addPolyline() {
  if (polyline) map.remove(polyline)
  const path = [
    userStore.getCenterLocal.map(Number), // 仓库的经纬度
    ...storeOrderList.value.map(({ lon, lat }) => [Number(lon), Number(lat)])
  ]
  // const path = storeOrderList.value.map(({ lon, lat }) => [Number(lon), Number(lat)])
  polyline = new AMap.Polyline({
    path: path, // 设置线覆盖物路径
    showDir: true,
    // dirImg:canvasDir,
    strokeColor: '#3366cc', // 线颜色
    strokeWeight: 10 // 线宽
  })
  map.add(polyline)
}

// 信息窗体
function initWindow(e) {
  const extData = e.target.getExtData()

  const orders = storeOrderList.value
    .filter((item) => item.store_id === extData.store_id)
    .map((item, index) => {
      return `
        ${index > 0 ? '<div style="border-bottom: 1px solid #ccc;margin: 4px 0;"></div>' : ''}
        <span>单据号：${item.no} - ${item.type === 1 ? '销' : '退'}</span>
        <p style="margin-block: 0;">
          <span>订单金额：${item.order_amount}</span>
          <span>体积：${item.totalVolume}</span>
          <span>重量：${item.totalWidth}</span>
        </p>
      `
    })
  const content = `
    <div style="display:flex;flex-direction:column;gap:2px;border: 1px solid #ccc; padding: 10px;background-color: #fff;font-size: 12px">
      <span style="font-weight: bold">门店名称:${extData.name} - 共${orders.length}单</span>
      <span>${extData.address}</span>
  `
  const infoWindow = new AMap.InfoWindow({
    content: content + orders.join('') + '</div>',
    anchor: 'bottom-center',
    isCustom: true,
    closeWhenClickMap: true,
    offset: [10, -30]
  })
  return infoWindow
}

onMounted(initMap)
onActivated(getStoreOrderList)
onUnmounted(() => {
  map.value?.destroy()
})

// 右侧订单区域
const listRef = ref()
const storeOrderList = ref([])
async function getStoreOrderList() {
  try {
    const params = {
      id: route.query.id
    }
    const res = await taskApi.detailLoad(params)
    storeOrderList.value = res.data.data.map((item, index) => {
      // 累加 item.detail 中的 total_price 字段
      const totalPriceSum = item?.detail?.reduce((sum, detailItem) => {
        return sum + Number(detailItem.total_price)
      }, 0)

      // 累加 item.detail 中的 volume 字段
      const totalVolume = item?.detail?.reduce((sum, detailItem) => {
        return sum + Number(detailItem.volume)
      }, 0)

      // 累加 item.detail 中的 weight 字段
      const totalWidth = item?.detail?.reduce((sum, detailItem) => {
        return sum + Number(detailItem.weight)
      }, 0)

      return {
        order_id: item.delivery.order_id,
        id: item.id,
        name: item?.store?.store_name,
        store_id: item?.store?.id,
        lon: item?.store?.lon,
        lat: item?.store?.lat,
        address: item?.store?.address,
        order_amount: totalPriceSum,
        goods: item.detail,
        totalVolume,
        totalWidth,
        no: item.no,
        type: item.delivery.type,
        create_time: item.create_time,
        salesman_rename: item?.salesman?.rename,
        remark: item.remark
      }
    })
    map?.clearMap()
    addMarker()
    addPolyline()
  } catch (error) {
    if (error?.msg) {
      message.error(error.msg)
    }
  }
}

async function delLoadOrder(data) {
  Modal.confirm({
    title: '提示',
    content: `确定要剔除${data.name}的订单吗?`,
    okText: '删除',
    okType: 'danger',
    async onOk() {
      try {
        if (data.is_add) {
          storeOrderList.value = storeOrderList.value.filter((item) => item.id !== data.id)
          selectedRowList.value = selectedRowList.value.filter((item) => item.id !== data.id)
          selectedRowKeyList.value = selectedRowKeyList.value.filter((item) => item !== data.id)
        } else {
          await taskApi.delLoadOrder({ id: route.query.id, order_ids: data.order_id })
          getStoreOrderList()
        }
        message.success('删除成功')
      } catch (e) {
        message.error(e.msg)
      }
    },
    cancelText: '取消',
    onCancel() {}
  })
}

// 已选择的销售订单合计信息
const salesOrderInfo = computed(() => {
  return _.filter(storeOrderList.value, (item) => item.type === 1)
})
// 已选择的退货订单合计信息
const refundOrderInfo = computed(() => {
  return _.filter(storeOrderList.value, (item) => item.type === 2)
})
// 体积
const checkedOrderVolumeTotal = computed(() => {
  return {
    sales: _.sumBy(salesOrderInfo.value, 'totalVolume').toFixed(2),
    refund: _.sumBy(refundOrderInfo.value, 'totalVolume').toFixed(2)
  }
})
// 重量
const checkedOrderWeightTotal = computed(() => {
  return {
    sales: _.sumBy(salesOrderInfo.value, 'totalWidth').toFixed(2),
    refund: _.sumBy(refundOrderInfo.value, 'totalWidth').toFixed(2)
  }
})
// 金额
const checkedOrderAmountTotal = computed(() => {
  return {
    sales: _.sumBy(salesOrderInfo.value, 'order_amount'),
    refund: _.sumBy(refundOrderInfo.value, 'order_amount')
  }
})
// 数量
const checkedOrderCountTotal = computed(() => {
  const chartMap = new Map([
    ['整'.charCodeAt(0), 0],
    ['中'.charCodeAt(0), 0],
    ['散'.charCodeAt(0), 0]
  ])
  const unitTypeMap = new Map([
    [GOODS_UNIT_TYPE.LARGE.value, '整'.charCodeAt(0)],
    [GOODS_UNIT_TYPE.MIDDLE.value, '中'.charCodeAt(0)],
    [GOODS_UNIT_TYPE.SMALL.value, '散'.charCodeAt(0)]
  ])

  function handleData(item: any) {
    return item.goods.map((item) => {
      return {
        numbers: item.num,
        chinese: unitTypeMap.get(item.spec.unit_type)
      }
    })
  }

  function sumBy(params: any, source: Map<number | undefined, number>) {
    const sourceKey = params.chinese
    const sourceNum = source.get(sourceKey)
    source.set(sourceKey, Number(sourceNum) + Number(params.numbers))
    return source
  }
  return {
    sales: _(salesOrderInfo.value)
      .map(handleData)
      .flatMapDeep()
      .reduce((prev, cur) => sumBy(cur, prev), _.cloneDeep(chartMap))
      .entries()
      .map(([chinese, number]) => [number, String.fromCharCode(chinese as number)])
      .toArray()
      .map((item) => item.join(''))
      .join(''),
    refund: _(refundOrderInfo.value)
      .map(handleData)
      .flatMapDeep()
      .reduce((prev, cur) => sumBy(cur, prev), _.cloneDeep(chartMap))
      .entries()
      .map(([chinese, number]) => [number, String.fromCharCode(chinese as number)])
      .toArray()
      .map((item) => item.join(''))
      .join('')
  }
})

// 新增配送单
const showSubmit = ref(false)
function changeSubmitModal(flag: boolean) {
  if (flag) {
    queryData()
  } else {
    selectedRowKeyList.value = []
  }
  showSubmit.value = flag
}
function addOrder() {
  storeOrderList.value = _.uniqBy([...storeOrderList.value, ...selectedRowList.value], 'id')
  addMarker()
  addPolyline()
  changeSubmitModal(false)
}

// 表头配置
const columns = [
  {
    title: '单据编号',
    dataIndex: 'no',
    width: 260
  },
  {
    title: '订单数量',
    dataIndex: 'order_number'
  },
  {
    title: '业务员',
    dataIndex: ['salesman', 'rename']
  },
  {
    title: '门店',
    dataIndex: ['store', 'store_name']
  },
  {
    title: '备注',
    dataIndex: 'remark'
  },
  {
    title: '片区',
    dataIndex: ['store', 'region', 'name']
  },
  {
    title: '订单金额',
    dataIndex: 'detail_sum'
  },
  {
    title: '经销商',
    dataIndex: ['dealer', 'name']
  },
  {
    title: '仓库',
    dataIndex: ['warehouse', 'name']
  },
  {
    title: '单据日期',
    dataIndex: 'create_time',
    fixed: 'right'
  }
]
const { queryForm, tableData, tableLoading, total, resetQuery, onSearch, queryData } = useQuery({
  fetchDataApi: async (params) => {
    const res = await salesApi.queryList(params)
    return {
      list: res.data.data.map((item) => ({ order_id: item.id, ...item })),
      total: res.data.total
    }
  },
  queryFormFilter: {
    no: '',
    order_type: undefined,
    create_time: [],
    type: 1,
    is_delivery: 1,
    is_self: 1,
    status: '2,6'
  },
  queryFormOp: {
    no: QUERY_FORM_OP['模糊查询'],
    order_type: QUERY_FORM_OP['全等查询'],
    create_time: QUERY_FORM_OP['范围查询'],
    type: QUERY_FORM_OP['全等查询'],
    is_delivery: QUERY_FORM_OP['不等查询'],
    is_self: QUERY_FORM_OP['不等查询'],
    status: QUERY_FORM_OP['IN查询']
  }
})
const selectedRowKeyList = ref([])
const selectedRowList = ref([])
function onSelectChange(selectedRowKeys, rows) {
  selectedRowKeyList.value = selectedRowKeys
  selectedRowList.value = rows.map((item) => {
    // 累加 item.detail 中的 total_price 字段
    const totalPriceSum = item?.detail?.reduce((sum, detailItem) => {
      return sum + Number(detailItem.total_price)
    }, 0)

    // 累加 item.detail 中的 num 字段
    const totalNumber = item?.detail?.reduce((sum, detailItem) => {
      return sum + Number(detailItem.num)
    }, 0)

    // 累加 item.detail 中的 volume 字段
    const totalVolume = item?.detail?.reduce((sum, detailItem) => {
      return sum + Number(detailItem.volume)
    }, 0)

    // 累加 item.detail 中的 weight 字段
    const totalWidth = item?.detail?.reduce((sum, detailItem) => {
      return sum + Number(detailItem.weight)
    }, 0)
    return {
      order_id: item.order_id,
      id: item.id,
      name: item?.store?.store_name,
      store_id: item.store?.id,
      lon: item?.store?.lon,
      lat: item?.store?.lat,
      address: item?.store?.address,
      order_amount: totalPriceSum,
      totalNumber: totalNumber,
      totalVolume,
      totalWidth,
      no: item.no,
      type: item.order_type,
      is_add: true
    }
  })
}

// 提交
async function submitTask() {
  const params = {
    id: route.query.id,
    order_ids: JSON.stringify(storeOrderList.value.map((item) => ({ id: item.order_id, is_delete: 0 }))),
    driver_id: route.query.driver_id,
    escort_driver_id: route.query.escort_driver_id === 'undefined' ? '' : route.query.escort_driver_id,
    status: 1,
    sort: JSON.stringify(storeOrderList.value.map((item, index) => ({ order_id: item.order_id, sort: index + 1 })))
  }
  try {
    const res = await taskApi.editLoad(params)
    message.success(res.msg)
    getStoreOrderList()

    showSubmit.value = false
    router.back()
  } catch (error) {
    message.error(error.msg)
  }
}
</script>
<style lang="less" scoped>
.map-wrapper {
  position: relative;
  width: 100%;
  height: 100%;
  #container {
    width: 100%;
    height: auto;
  }
  .order-box {
    position: absolute;
    right: 0;
    top: 0;
    width: 450px;
    .store-order-item {
      position: relative;
      width: 90%;
      font-size: 12px;
      padding: 10px;
      margin-bottom: 5px;
      border-radius: 5px;
      background-color: #f8f9ff;
      cursor: pointer;
      border: 1px solid transparent;
      .no {
        position: absolute;
        left: 15px;
        top: 50%;
        transform: translateY(-50%);
        font-size: 14px;
      }
      .content {
        display: flex;
        flex-direction: column;
        padding-left: 30px;
        width: 100%;
        p {
          width: 100%;
          margin: 0;
          // white-space: nowrap;
          // overflow: hidden;
          // text-overflow: ellipsis;
        }
        .line {
          color: #8085a2;
        }
        .line span {
          color: #000;
        }
      }
      .order-info-line {
        display: flex;
        gap: 5px;
        align-items: center;
      }
    }
    .store-order-item.active,
    .store-order-item:hover {
      background-color: #eaf4f0;
      border: 1px solid @primary-color;
    }
  }
  .order-box-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 12px;
  }
  .total-box {
    position: absolute;
    left: -100%;
    bottom: 0px;
    transform: translateX(60%);
    font-size: 12px;
    .total-box-line {
      display: flex;
      justify-content: space-between;
      margin-bottom: 0;
      strong {
        font-size: 14px;
      }
      span {
        width: fit-content;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
    }
  }
}
</style>
